wait関数は、呼び出し元プロセスの子プロセスの状態変化を待ちます。子プロセスの状態変化がすでに発生していた場合は、wait関数はすぐに復帰します。それ以外の場合は、子プロセスの状態変化が起こるか、シグナルハンドラによりシステムコールが中断されるまで呼び出し元プロセスは停止します。
なお、ここでの状態変化には、次のような事があります。
- 子プロセスの終了。
- シグナルによる子プロセスの停止。
- シグナルによる子プロセスの再開。
この関数は、C言語のライブラリ関数(標準関数)ではありませんので、コンパイラにより、使えない場合があります。
#include <sys/wait.h>
pid_t wait(int *status);
*statusは子プロセスからの終了ステータスを格納する変数を指定します。なお、終了ステータスが不要な場合は、NULLを指定できます。
戻り値として、処理が成功した場合は、子プロセスのプロセスIDが、失敗した場合は-1を返します。
終了ステータスはexit関数の引数で指定した値そのままではなく、「指定した値 & 0377」です。また、終了ステータスをチェックするための、次のようなマクロがあります。
マクロ | 内容 |
---|---|
WIFEXITED(status) | 子プロセスが正常に終了した場合に真を返します。「正常」とは、exit関数の呼び出しや、main関数から復帰した場合です。 |
WEXITSTATUS(status) | 子プロセスの終了ステータスを返します。終了ステータスはexit関数やmain関数の引数で指定した値です。なお、このマクロはWIFEXITEDマクロが真を返した場合だけ使用したほうがよいでしょう。 |
WIFSIGNALED(status) | 子プロセスがシグナルにより終了した場合に真を返します。 |
WTERMSIG(status) | 子プロセス終了の原因となったシグナルの番号を返します。このマクロはWIFSIGNALEDマクロが真を返した場合だけ使用したほうがよいでしょう。 |
プログラム 例
#include <stdio.h> #include <sys/wait.h> int main() { int p_id; int status; int return_code = 0; if ((p_id = fork()) == 0) { /* 子プロセス */ printf("子プロセス開始\n"); sleep(10); printf("子プロセス終了\n"); } else { /* 親プロセス */ if (p_id != -1) { /* 子プロセスの状態変化を待つ */ wait(&status); /* 終了ステータスのチェック */ if (WIFEXITED(status)) { printf("親プロセス : 子プロセスは終了ステータス%dで正常終了しました\n", WEXITSTATUS(status)); } if (WIFSIGNALED(status)) { printf("親プロセス : 子プロセスはシグナル番号%dで終了しました\n", WTERMSIG(status)); } printf("親プロセス終了\n"); } else { perror("親プロセス "); return_code = 1; } } return return_code; }
例の実行結果
2回目と3回目はバックグラウンドで実行して、psコマンドで子プロセスのプロセスIDを調べた後、killコマンドでシグナルを送っています。(その結果、子プロセスは終了します。)
$ ./wait.exe 子プロセス開始 子プロセス終了 親プロセス : 子プロセスは終了ステータス0で正常終了しました 親プロセス終了 $ $ ./wait.exe & 子プロセス開始 [1] 2731 $ ps PID TTY TIME CMD 2293 pts/1 00:00:00 bash 2731 pts/1 00:00:00 wait.exe 2732 pts/1 00:00:00 wait.exe 2733 pts/1 00:00:00 ps $ kill 2732 親プロセス : 子プロセスはシグナル番号15で終了しました 親プロセス終了 $ $ ./wait.exe & 子プロセス開始 [1] 2741 $ ps PID TTY TIME CMD 2293 pts/1 00:00:00 bash 2741 pts/1 00:00:00 wait.exe 2742 pts/1 00:00:00 wait.exe 2743 pts/1 00:00:00 ps $ kill -s SIGQUIT 2742 親プロセス : 子プロセスはシグナル番号3で終了しました 親プロセス終了 $